mod tokens;
use core::sync;
use std::{env, fs};

use self::tokens::tokenize;
use pest_derive::Parser;

#[derive(Parser)]
#[grammar = "lexer.pest"] // 指向你的 .pest 文件
struct SysYLexer;

fn main() {
    // 收集命令行参数
    let args: Vec<String> = env::args().collect();

    // 检查是否提供了文件名
    if args.len() < 2 {
        eprintln!("Usage: {} <filename>", args[0]);
        std::process::exit(1);
    }

    // 获取文件名
    let filename = &args[1];

    // 读取输入文件
    let input = fs::read_to_string(filename).expect("Failed to read file");

    // 进行词法分析
    let tokens = tokenize(&input);

    // 打印所有的 token
    match tokens {
        Ok(toks) => {
            let mut result: Vec<(String, String, usize)> = Vec::new();
            for token in toks {
                match token {
                    tokens::Token::Integer(value, _original_text, line) => {
                        result.push(("INTEGER_CONST".to_string(), value.to_string(), line));
                    }
                    tokens::Token::Operator(op, op_text, line) => {
                        result.push((op, op_text, line));
                    }
                    tokens::Token::Keyword(kw, kw_text, line) => {
                        result.push((kw, kw_text, line));
                    }
                    tokens::Token::Identifier(id, line) => {
                        result.push(("IDENT".to_string(), id, line));
                    }
                    tokens::Token::Symbol(symbol, symbol_text, line) => {
                        result.push((symbol, symbol_text, line));
                    }
                    tokens::Token::Whitespace => {
                        // 忽略空白符
                        continue;
                    }
                    tokens::Token::Comment => {
                        // 忽略注释
                        continue;
                    }
                    tokens::Token::EOI => {
                        // 忽略文件结束符
                        continue;
                    }
                }
            }
            for item in &result {
                eprintln!("{} {} at Line {}.", item.0, item.1, item.2);
            }
        }
        Err(err) => {
            for (line, message) in err {
                eprintln!("Error type A at Line {}: Mysterious character \"{}\".", line, message);
            }
        }
    }
}
